<?php

namespace app\api\controller;

use addons\crontab\model\Crontab;
use app\admin\model\Activity;
use app\admin\model\ActivityApply;
use app\admin\model\Adv;
use app\admin\model\Banner;
use app\common\controller\Api;
use Cron\CronExpression;
use think\Db;

/**
 * 首页接口
 */
class Index extends Api
{
    protected $noNeedLogin = ['banner','activity','activityDetail','config','task','adv','tongzhi'];
    protected $noNeedRight = ['*'];

    /**
     * 首页
     *
     */
    public function banner()
    {
        $list = Banner::order('weigh desc')->select();
        $this->success('请求成功',$list);
    }

    public function adv()
    {
        $list = Adv::order('weigh desc')->select();
        $this->success('请求成功',$list);
    }

    //活动列表
    public function activity()
    {
        $list = Activity::order('weigh desc')->select();
        $this->success('请求成功',$list);
    }

    //活动通知
    public function tongzhi()
    {
        $auth = new \app\common\library\Auth();

        $list = ActivityApply::alias('aa')
            ->join('activity a', 'a.id=aa.activity_id', 'LEFT')
            ->field('a.id,a.name,a.place,a.start_time,a.end_time,aa.user_id')
            ->order('start_time asc')->select();
        foreach ($list as $k=>$v){
            if (strtotime($v['start_time'])-time()<86400/2){
                $user = \app\admin\model\User::get($v['user_id']);
                $param_data = array(
                    'date2'=>array('value'=>$v['start_time']),
                    'date3'=>array('value'=>$v['end_time']),
                    'time4'=>array('value'=>$v['name']),
                    'thing7'=>array('value'=>$v['place']),
                );
                $page = '/otherpages/activityDetail/activityDetail?id='.$v['id'];
                $call_template_id = 'QtSo-19yUcQo0C2XQXvUBf6v_ljKfLublYzeK207Ouw';//
                $template_res = $auth->sendmessage($user->wechat_open_id,$page,$param_data,$call_template_id);
            }
        }

        $this->success('通知成功');
    }

    //活动详情
    public function activityDetail()
    {
        $id = input('id',0);
        $detail = Activity::get($id);
        $this->success('请求成功',$detail);
    }

    //活动是否报名
    public function isSignup()
    {
        $activity_id = input('activity_id',0);
        $detail = ActivityApply::get(['activity_id'=>$activity_id,'user_id'=>$this->auth->id]);
        $this->success('请求成功',$detail?1:0);
    }

    //活动报名
    public function activitySignup()
    {
        $model = new ActivityApply();
        $data = [
            'user_id'=>$this->auth->id,
            'activity_id'=>input('activity_id',0),
            'realname'=>input('realname',0),
            'mobile'=>input('mobile',0),
            'people_num'=>input('people_num',0),
        ];
        $model->save($data);
        $this->success('请求成功');
    }


    //配置
    public function config()
    {
        $data = [
            'logo'=>\app\common\model\Config::get(['name'=>'logo'])->value,
            'group_qrcode'=>\app\common\model\Config::get(['name'=>'group_qrcode'])->value,
            'kefu_mobile'=>\app\common\model\Config::get(['name'=>'kefu_mobile'])->value,
            'aboutus'=>\app\common\model\Config::get(['name'=>'aboutus'])->value,
            'privacy_agreement'=>\app\common\model\Config::get(['name'=>'privacy_agreement'])->value,
            'user_agreement'=>\app\common\model\Config::get(['name'=>'user_agreement'])->value,
        ];
        $this->success('请求成功',$data);
    }


    /**
     * 执行定时任务
     */
    public function task()
    {
        $withPcntl = false;
        $pool = null;

        $config = get_addon_config('crontab');
        $mode = $config['mode'] ?? 'pcntl';
        if ($mode == 'pcntl' && function_exists('pcntl_fork')) {
            $withPcntl = true;
            $pool = new \Jenner\SimpleFork\Pool();
        }

        $time = time();
        $logDir = LOG_PATH . 'crontab' . DS;
        if (!is_dir($logDir)) {
            mkdir($logDir, 0755);
        }
        //筛选未过期且未完成的任务
        $crontabList = Crontab::where('status', '=', 'normal')->order('weigh DESC,id DESC')->select();
        $execTime = time();
        foreach ($crontabList as $crontab) {
            $update = [];
            $execute = false;
            if ($time < $crontab['begintime']) {
                //任务未开始
                continue;
            }
            if ($crontab['maximums'] && $crontab['executes'] > $crontab['maximums']) {
                //任务已超过最大执行次数
                $update['status'] = 'completed';
            } else {
                /*if ($crontab['endtime'] > 0 && $time > $crontab['endtime']) {
                    //任务已过期
                    $update['status'] = 'expired';
                } else {*/
                    //重复执行
                    //如果未到执行时间则继续循环
                    $cron = CronExpression::factory($crontab['schedule']);
                    if (!$cron->isDue() || ($crontab['executetime'] && date("YmdHi", $execTime) === date("YmdHi", $crontab['executetime']))) {
                        continue;
                    }
                    $execute = true;
                //}
            }

            // 如果允许执行
            if ($execute) {
                $update['executetime'] = $time;
                $update['executes'] = $crontab['executes'] + 1;
                $update['status'] = ($crontab['maximums'] > 0 && $update['executes'] >= $crontab['maximums']) ? 'completed' : 'normal';
            }

            // 如果需要更新状态
            if (!$update) {
                continue;
            }
            // 更新状态
            $crontab->save($update);
            Db::connect()->close();
            // 将执行放在后面是为了避免超时导致多次执行
            if (!$execute) {
                continue;
            }

            $runnable = new \addons\crontab\library\CommandRunnable($crontab);
            if ($withPcntl) {
                $process = new \Jenner\SimpleFork\Process($runnable);
                $name = $crontab['title'];
                $pool->execute($process);
            } else {
                $runnable->run();
            }

        }
        if ($withPcntl && $pool) {
            $pool->wait();
        }
        return "Execute completed!\n";
    }
}
